package com.lanhai.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.lanhai.MainAction;
import com.lanhai.enums.AgvState;
import com.lanhai.enums.CaFlag;
import com.lanhai.enums.GpType;
import com.lanhai.enums.LoadState;
import com.lanhai.enums.Step;
import com.lanhai.javaBean.AgvBean;
import com.lanhai.model.Agv;
import com.lanhai.model.CacheShelf;
import com.lanhai.model.ControlArea;
import com.lanhai.model.Guidepost;
import com.lanhai.model.Park;
import com.lanhai.model.Path;
import com.lanhai.model.Station;
import com.lanhai.model.TrafficWait;
import com.lanhai.utils.CommandUtil;
import com.lanhai.utils.DateUtil;
import com.lanhai.utils.HexUtil;
import com.lanhai.utils.RegionUtil;
import com.lanhai.utils.UDPUtil;

/**
 * 任务管理
 */
public class TaskAction {
	private static final Logger logger = Logger.getLogger(TaskAction.class);
	private MainAction mainAction;
	private static double RADIUS = 300.0;// 机台的范围半径(单位：厘米)

	public void init(MainAction deal) {
		mainAction = deal;
	}

	/**
	 * 处理机台发送过来的数据
	 */
	public void handle(byte[] buf, String ipAddress, int port) {
		mainAction.main.pool.execute(new Runnable() {
			@Override
			public void run() {
				String mwStr = HexUtil.byte2HexStr(buf);
				String line = mwStr.substring(0, 2);
				String note = "接收数据" + mwStr + ",IP地址：" + ipAddress;
				Station station = mainAction.getStationByIp(ipAddress, port);
				byte[] in = { 0, 0, 0, buf[10] };
				int agentId = CommandUtil.toIntH(in);
				if (station == null) {
					station = mainAction.getStationByAgentId(agentId);
				}
				if (station != null && !station.getAgentIpAddress().equals("0")) {
					byte agentStationId = (byte) station.getAgentId();
					byte[] agentData = new byte[11];
					for (int i = 0; i < agentData.length - 1; i++) {
						agentData[i] = buf[i];
					}
					agentData[10] = agentStationId;
					logger.info("代理转发" + station.getName() + "数据：" + HexUtil.byte2HexStr(agentData));
					UDPUtil.sendData4Agent(agentData, station.getAgentIpAddress(), station.getAgentPort());
					return;
				}
				List<Station> staList = mainAction.getStationListByIp(ipAddress, port);
				if (staList.size() == 0) {
					staList = mainAction.getStationListByAgentId(agentId);
				}
				mainAction.main.saveInputLog(port, line, mwStr, note, "Station", line,
						DateUtil.getTimeDate(new Date()));

				station.setLastReceiveTime(new Date());
				if (!station.isInitFlag()) {
					station.setInitFlag(true);
				}
				Step step = Step.getStepByCode(station.getStep());
				if (station.getType() == 3) {
					// 缓存机的数据处理
					saveCacheShelf(station, buf);
				} else {
					// 上下料机及翻篮机处理
					switch (step) {
					case ZRS:
						// 处理制绒上料数据
						handle4zrs(buf, station);
						break;
					case ZRX:
						// 处理制绒下料数据
						handle4zrx(buf, station);
						break;
					case KSX:
						// 处理扩散数据
						handle4ks(buf, station);
						break;
					case SE:
						// 处理激光数据
						handle4se(buf, station);
						break;
					case QY:
						// 处理前氧数据
						handle4qy(buf, station);
						break;
					case JPS:
						// 处理碱抛数据
						handle4jp(buf, station);
						break;
					case JPX:
						// 处理碱抛下料数据
						handle4jp(buf, station);
						break;
					case HYS:
						// 处理后氧上料数据
						handle4ks(buf, station);
						break;
					case JPFK:
						// 处理碱抛返空数据
						handle4jp(buf, station);
						break;
					case KSS:
						// 处理扩散上料数据
						handle4ks(buf, station);
						break;
					case HYX:
						// 处理后氧下料
						handle4ks(buf, station);
						break;
					case ALD:
					case ALDX:
						// 处理ALD上料
						// 处理ALD下料
						handle4FlowerBasket4ALD(buf, staList);
						break;
					case PEB:
					case PEBX:
						// 处理PE背膜上料
						// 处理PE背膜下料
						handle4FlowerBasket(buf, staList);
						break;
					case PEZ:
					case PEZX:
						// 处理PE正膜上料
						// 处理PE正膜下料
						handle4FlowerBasket(buf, staList);
						break;
					case SW:
						// 处理丝网
						handle4se(buf, station);
						break;
					}
				}

				// 检查对接AGV是否离开
				checkAgvInside(station);
				mainAction.main.stationMap.put(station.getName(), station);
				try {
					logger.info("statinId:" + station.getId() + ",joinAgvId:" + station.getJoinAgvId());
					mainAction.updateTempStation(station.getName());
				} catch (Exception e) {
					logger.error("Exception:", e);
				}
			}
		});
	}

	/**
	 * Park的座标不可用，应该用guidepost的座标
	 * 
	 * @param station
	 */
	private void checkAgvInside(Station station) {
		if (station.getJoinAgvId() > 0) {
			Agv agv = mainAction.main.agvMap.get(station.getJoinAgvId());
			// 用station的innum来定位机台的位置范围
			Guidepost gp = mainAction.getGuidepostByNum(station.getInNum());
			double distance = RegionUtil.distance(gp.getMapX(), gp.getMapY(), agv.getCurrentX(), agv.getCurrentY());
			logger.info("Agv:" + agv.getId() + ",与机台【" + station.getName() + "】中心差距：" + distance);
			// 两点相距超过设定的半径则认为AGV已经不在机台,机台的joinAgvId设为“0”
			if (distance > RADIUS) {
				// logger.info("离开了机台范围？？？？？？？？？？？？？？？？？？？");
				// station.setJoinAgvId(0);
			}
		}
	}

	/**
	 * 对接制绒上料机数据
	 * 
	 * @param buf
	 * @param station
	 */
	private void handle4zrs(byte[] buf, Station station) {
		int isWait = buf[2];// 进料对接位，0：不对接，1：对接
		int isWait2 = buf[3];// 出料对接位，0：不对接，1：对接
		int inQuantity = buf[4] + buf[5]; // 花篮数量

		station.setIsWait(isWait);
		station.setIsWait2(isWait2);
		station.setInQuantity(inQuantity);
		station.setControlState(buf[1]);// 保存系统状态

		mainAction.main.stationMap.put(station.getName(), station);
	}

	/**
	 * 对接制绒下料机数据
	 * 
	 * @param buf
	 * @param station
	 */
	private void handle4zrx(byte[] buf, Station station) {
		int isWait = buf[2];// 进料对接位，0：不对接，1：对接
		int isWait2 = buf[3];// 出对接位，0：不对接，1：对接
		int outQuantity = buf[4] + buf[5]; // 花篮数量

		station.setIsWait(isWait);
		station.setIsWait2(isWait2);
		station.setOutQuantity(outQuantity);
		station.setControlState(buf[1]);

		mainAction.main.stationMap.put(station.getName(), station);
	}

	/**
	 * 对接扩散上、下料机
	 * 
	 * @param buf
	 * @param station
	 */
	private void handle4ks(byte[] buf, Station station) {
		int isWait = buf[2];
		int isWait2 = buf[4];
		int inQuantity = buf[6];
		int outQuantity = buf[8];
		station.setIsWait(isWait);
		station.setIsWait2(isWait2);
		station.setInQuantity(inQuantity);
		station.setOutQuantity(outQuantity);
		mainAction.main.stationMap.put(station.getName(), station);
	}

	/**
	 * 对接ALD上、下料机
	 * 
	 * @param buf
	 * @param station
	 */
	private void handle4FlowerBasket(byte[] buf, List<Station> staList) {
		if (staList.size() > 0) {
			for (Station station : staList) {
				int isWait = buf[2];
				int isWait2 = buf[4];
				int inQuantity = buf[6];
				int outQuantity = buf[8];
				station.setIsWait(isWait);
				station.setIsWait2(isWait2);
				station.setInQuantity(inQuantity);
				station.setOutQuantity(outQuantity);
				mainAction.main.stationMap.put(station.getName(), station);
			}
		}

	}

	/**
	 * 对接ALD上、下料机
	 * 
	 * @param buf
	 * @param station
	 */
	private void handle4FlowerBasket4ALD(byte[] buf, List<Station> staList) {
		if (staList.size() > 0) {
			for (Station station : staList) {
				int isWait = buf[2];
				int isWait2 = buf[4];
				int inQuantity = buf[6] + buf[7];
				int outQuantity = buf[8] + buf[9];
				int outLeftStop = buf[5];
				int outRightStop = buf[3];
				station.setOutLeftStop(outLeftStop);
				station.setOutRightStop(outRightStop);
				station.setIsWait(isWait);
				station.setIsWait2(isWait2);
				station.setInQuantity(inQuantity);
				station.setOutQuantity(outQuantity);
				mainAction.main.stationMap.put(station.getName(), station);
			}
		}

	}

	public void callAgv4ks(Station station) {
		if (station.getIsWait() == 1 || station.getIsWait2() == 1) {
			List<Agv> waitAgvList = new ArrayList<Agv>();
			boolean isRun = true;
			for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
				if (m.getValue().getLastPoint() == 117 || m.getValue().getLastPoint() == 145
						|| m.getValue().getLastPoint() == 146 || m.getValue().getLastPoint() == 200) {
					waitAgvList.add(m.getValue());
				}
				if (m.getValue().getGoal() == 59 || m.getValue().getGoal() == 61 || m.getValue().getLastPoint() == 60
						|| m.getValue().getLastPoint() == 62) {
					isRun = false;
				}
			}
			// 按等待时间排序
			AgvBean.waitParkTimeSort(waitAgvList);
			if (isRun && waitAgvList.size() > 0) {
				for (Agv wa : waitAgvList) {
					if (wa.getLoadState() == LoadState.MK.getCode() && station.getIsWait() == 1) {
						station.setJoinAgvId(wa.getId());
						mainAction.main.stationMap.put(station.getName(), station);
						wa.setGoal(station.getInNum());
						mainAction.main.agvMap.put(wa.getId(), wa);
						if (wa.getLastPoint() == 117) {
							mainAction.agvAction.joinComplete(wa.getId());
						} else {
							multiPath4z(wa, wa.getLastPoint(), station.getInNum());
						}
						break;
					}
					if (wa.getLoadState() == LoadState.KK.getCode() && station.getIsWait2() == 1) {
						station.setJoinAgvId(wa.getId());
						mainAction.main.stationMap.put(station.getName(), station);
						wa.setGoal(station.getInNum());
						mainAction.main.agvMap.put(wa.getId(), wa);
						if (wa.getLastPoint() == 117) {
							mainAction.agvAction.joinComplete(wa.getId());
						} else {
							multiPath(wa, wa.getLastPoint(), station.getInNum());
						}
						break;
					}
				}
			}
		}
	}

	private void handle4fl(byte[] buf, Station station) {
		int isWait = buf[3];
		int isWait2 = buf[5];
		if (station.getIsWait() != isWait) {
			station.setIsWait(buf[3]);
			if (isWait == 1) {
				station.setWaitTime(new Date());
			} else {
				station.setWaitTime(null);
			}
		}
		if (station.getIsWait2() != isWait2) {
			station.setIsWait2(buf[5]);
		}
		mainAction.main.stationMap.put(station.getName(), station);
	}

	/**
	 * 对接SE上下料
	 * 
	 * @param buf
	 * @param station
	 */
	private void handle4se(byte[] buf, Station station) {
		int isWait = buf[2];
		int isWait2 = buf[4];
		int inQuantity = buf[6];
		int outQuantity = buf[8];
		station.setIsWait(isWait);
		station.setIsWait2(isWait2);
		station.setInQuantity(inQuantity);
		station.setOutQuantity(outQuantity);
		mainAction.main.stationMap.put(station.getName(), station);
	}

	/**
	 * 对接前氧上下料
	 * 
	 * @param buf
	 * @param staiton
	 */
	private void handle4qy(byte[] buf, Station station) {
		int isWait = buf[2];
		int isWait2 = buf[4];
		int inQuantity = buf[6];
		int outQuantity = buf[8];
		station.setIsWait(isWait);
		station.setIsWait2(isWait2);
		station.setInQuantity(inQuantity);
		station.setOutQuantity(outQuantity);
		mainAction.main.stationMap.put(station.getName(), station);
	}

	/**
	 * 对接碱抛上下料
	 * 
	 * @param buf
	 * @param station
	 */
	private void handle4jp(byte[] buf, Station station) {
		int isWait = buf[2];
		int isWait2 = buf[4];
		int inQuantity = buf[6] + buf[7];
		int outQuantity = buf[8] + buf[9];
		station.setIsWait(isWait);
		station.setIsWait2(isWait2);
		station.setInQuantity(inQuantity);
		station.setOutQuantity(outQuantity);
		station.setControlState(buf[1]);
		if (station.getControlState() != 1) {
			Park park = mainAction.getParkByStationName(station.getName());
			String hexStr = station.getSname() + "000000000000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向碱抛机台发送进料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		}
		mainAction.main.stationMap.put(station.getName(), station);

	}

	/**
	 * 提取该工序的待命点
	 * 
	 * @param step
	 * @param pGroup
	 * @return
	 */
	public List<Park> getTempParkItem(int step, int xzdNumItem) {
		List<Park> tpList = new ArrayList<Park>();
		for (Map.Entry<Integer, Park> mp : mainAction.main.parkMap.entrySet()) {
			if (mp.getValue().getStep() == step && mp.getValue().getXzdNumItem() == xzdNumItem
					&& (mp.getValue().getType() == 2 || mp.getValue().getType() == 4)) {
				tpList.add(mp.getValue());
			}
		}
		return tpList;
	}

	public List<Park> getTempPark(int step, int pGroup, int area) {
		List<Park> tpList = new ArrayList<Park>();
		for (Map.Entry<Integer, Park> mp : mainAction.main.parkMap.entrySet()) {
			if (mp.getValue().getStep() == step
					&& (mp.getValue().getpGroup() == pGroup || mp.getValue().getpGroup() == 0)
					&& (mp.getValue().getType() == 2 || mp.getValue().getType() == 4)
					&& mp.getValue().getXzdNumItem() == area) {
				tpList.add(mp.getValue());
			}
		}
		return tpList;
	}

	public List<Park> getTempPark(int step, int pGroup) {
		List<Park> tpList = new ArrayList<Park>();
		for (Map.Entry<Integer, Park> mp : mainAction.main.parkMap.entrySet()) {
			if (mp.getValue().getStep() == step
					&& (mp.getValue().getpGroup() == pGroup || mp.getValue().getpGroup() == 0)
					&& (mp.getValue().getType() == 2 || mp.getValue().getType() == 4)) {
				tpList.add(mp.getValue());
			}
		}
		return tpList;
	}

	public List<Park> getTempPark(int step) {
		List<Park> tpList = new ArrayList<Park>();
		for (Map.Entry<Integer, Park> mp : mainAction.main.parkMap.entrySet()) {
			if (mp.getValue().getStep() == step && (mp.getValue().getType() == 2 || mp.getValue().getType() == 4)) {
				tpList.add(mp.getValue());
			}
		}
		return tpList;
	}

	/**
	 * 获取当前工序公用的充电桩
	 * 
	 * @param step
	 * @param park
	 * @return
	 */
	public List<Park> getTempChargerPark(int step, Park park) {
		List<Park> tpList = new ArrayList<Park>();
		for (Map.Entry<Integer, Park> mp : mainAction.main.parkMap.entrySet()) {
			if (mp.getValue().getStep() == step && mp.getValue().getType() == 2
					&& mp.getValue().getXzdNumItem() == park.getXzdNumItem()) {
				tpList.add(mp.getValue());
			}
		}
		return tpList;
	}

	/**
	 * 获取当前工序公用的充电桩,根据优先级
	 * 
	 * @param step
	 * @param park
	 * @return
	 */
	public List<Park> getTempChargerPark4Priority(int step, Park park) {
		List<Park> tpList = new ArrayList<Park>();
		for (Map.Entry<Integer, Park> mp : mainAction.main.parkMap.entrySet()) {
			if (mp.getValue().getStep() == step && mp.getValue().getType() == 2
					&& mp.getValue().getXzdNumItem() == park.getXzdNumItem()
					&& mp.getValue().getItem() < park.getItem()) {
				tpList.add(mp.getValue());
			}
		}
		return tpList;
	}

	/**
	 * 获取当前工序的公用充电泊位
	 * 
	 * @param step
	 * @param park
	 * @return
	 */
	public List<Park> getTempPublicChargerParkToStep(int Step, Park park) {
		List<Park> tpList = new ArrayList<Park>();
		for (Map.Entry<Integer, Park> mp : mainAction.main.parkMap.entrySet()) {
			if (mp.getValue().getStep() == park.getStep() && mp.getValue().getType() == 2
					&& mp.getValue().getSubType() == 1 && mp.getValue().getXzdNumItem() == park.getXzdNumItem()) {
				tpList.add(mp.getValue());
			}
		}
		return tpList;
	}

	/**
	 * 根据交管区状态放行AGV
	 * 
	 * @param ca
	 * @param agv
	 * @param data
	 * @param note
	 */
	public void driveAgv(List<ControlArea> caList, Agv agv, byte[] data, String note, String[] caIds) {
		logger.info("【放行车辆】");
		boolean runFlag = true;
		for (ControlArea ca : caList) {
			if (ca.getFlag() == CaFlag.OFF.getCode() && ca.getRunAgvId() != agv.getId()) {
				runFlag = false;// 不启动AGV
			}
			if (ca.getFlag() == CaFlag.LM.getCode()) {
				runFlag = false;// 不启动AGV
			}
		}

		if (runFlag) {// 可通行,或者占用交管区的为当前AGV
			logger.info("【满足放行条件!】");
			// 占用交管区
			for (ControlArea ca : caList) {
				if (ca.getFlag() == 1 && ca.getRunAgvId() == 0) {
					ca.setFlag(2);
					ca.setRunAgvId(agv.getId());
				} else if (ca.getFlag() == 3 && ca.getRunAgvId() == agv.getId()) {
					ca.setFlag(2);
				} else if (ca.getFlag() == 3 && ca.getRunAgvId() != agv.getId()) {
					ca.setFlag(2);
				}
				logger.info("【交管状态：" + ca.getFlag() + "】");
				mainAction.main.controlAreaMap.put(ca.getId(), ca);
			}
			mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());// ctrlState,1、行驶
		} else {// 不可通行，则将AGV放到等待列表中
			logger.info("【不满足放行条件!】");
			// 判断等待列表
			boolean newFlag = true;
			for (TrafficWait t : mainAction.main.waitAgvList) {
				if (t.getAgvId() == agv.getId()) {
					newFlag = false;
				}
			}
			if (newFlag) {
				TrafficWait tw = new TrafficWait();
				tw.setControlAreaIds(caIds);
				tw.setAgvId(agv.getId());
				tw.setRestartData(data);// 放行指令
				tw.setdStr(HexUtil.byte2HexStr(data));
				mainAction.main.waitAgvList.add(tw);
			}
		}
	}

	public void driveAgv(List<ControlArea> caList, Agv agv, byte[] data, String note, Guidepost lastGuidepost,
			int[] caIds) {
		logger.info("【放行车辆】");
		boolean runFlag = true;
		if (caList != null) {
			for (ControlArea ca : caList) {
				if (ca != null) {
					if (ca.getFlag() == CaFlag.OFF.getCode() && ca.getRunAgvId() != agv.getId()) {
						runFlag = false;// 不启动AGV
					}
					if (ca.getFlag() == CaFlag.LM.getCode() && lastGuidepost.getType() == GpType.JG.getCode()
							&& ca.getId() == lastGuidepost.getCaId()) {
						runFlag = false;// 不启动AGV
					}
				}
			}
		}

		if (runFlag) {// 可通行,或者占用交管区的为当前AGV
			logger.info("【满足放行条件!】");
			// 占用交管区
			for (ControlArea ca : caList) {
				if (ca != null) {
					if (ca.getFlag() == 1 && ca.getRunAgvId() == 0) {
						ca.setFlag(2);
						ca.setRunAgvId(agv.getId());
					} else if (ca.getFlag() == 3 && ca.getRunAgvId() == agv.getId()) {
						ca.setFlag(2);
					} else if (ca.getFlag() == 3 && ca.getRunAgvId() != agv.getId()) {
						ca.setFlag(2);
					}

					logger.info("【交管状态：" + ca.getFlag() + "】");
					mainAction.main.controlAreaMap.put(ca.getId(), ca);
				}
			}
			mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());// ctrlState,1、行驶
		} else {// 不可通行，则将AGV放到等待列表中
			logger.info("【不满足放行条件!】");
			// 判断等待列表
			boolean newFlag = true;
			for (TrafficWait t : mainAction.main.waitAgvList) {
				if (t.getAgvId() == agv.getId()) {
					newFlag = false;
				}
			}
			if (newFlag) {
				TrafficWait tw = new TrafficWait();
//				tw.setControlAreaIds(caIds);
//				tw.setGp(lastGuidepost);
				tw.setAgvId(agv.getId());
				tw.setRestartData(data);// 放行指令
				tw.setdStr(HexUtil.byte2HexStr(data));
				mainAction.main.waitAgvList.add(tw);
			}
		}
	}

	/**
	 * 向AGV下发路径
	 */
	public void specifyPath(Agv agv, int lastPoint, int nextPoint, String parkName, List<ControlArea> caList) {
		String pathKay = lastPoint + "_" + nextPoint;
		Path path = mainAction.main.mapPathMap.get(pathKay);
		if (path != null) {
			byte[] data = CommandUtil.pathway(agv.getId(), path.getItem());
			String note = "AGV启动，路径ID：" + path.getItem();
			// 更新Agv的迈为线号
			agv.setParkName(parkName);
			agv.setNextDot(pathKay);
			if (caList == null) {
				mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());// ctrlState,1、行驶
				// 刷新列表
				mainAction.main.agvMap.put(agv.getId(), agv);
			} else {// 判断交管区是否可通行
				StringBuffer sb = new StringBuffer();
				for (int i = 0; i < caList.size(); i++) {
					sb.append(caList.get(i).getId() + ",");
				}
				String[] caIds = sb.toString().split(",");
				driveAgv(caList, agv, data, note, caIds);
			}
		} else {
			String msg = "找不到对应线路，pathKay:" + pathKay;
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
	}

	public void specifyPath(Agv agv, int lastPoint, int nextPoint, List<ControlArea> caList) {
		String pathKay = lastPoint + "_" + nextPoint;
		Path path = mainAction.main.mapPathMap.get(pathKay);
		if (path != null) {
			byte[] data = CommandUtil.pathway(agv.getId(), path.getItem());
			String note = "AGV启动，路径ID：" + path.getItem();
			agv.setNextDot(pathKay);
			if (caList == null) {
				mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());// ctrlState,1、行驶
				// 刷新列表
				mainAction.main.agvMap.put(agv.getId(), agv);
			} else {// 判断交管区是否可通行
				int[] caIds = new int[caList.size()];
				for (int i = 0; i < caList.size(); i++) {
					caIds[i] = caList.get(i).getId();
				}
				Guidepost gp = mainAction.main.guidepostMap.get(lastPoint);
				driveAgv(caList, agv, data, note, gp, caIds);
			}
		} else {
			String msg = "找不到对应线路，pathKay:" + pathKay;
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
	}

	/**
	 * 根据起点和终点获取当前的线路
	 * 
	 * @param agv
	 * @param lastPoint
	 * @param nextPoint
	 * @param caList
	 */
	public void specifyPath4NumOrDot(Agv agv, int lastPoint, int nextPoint, List<ControlArea> caList) {
		String pathKay = lastPoint + "_" + nextPoint;
		Path path = mainAction.getPathByNumOrDot(String.valueOf(lastPoint), String.valueOf(nextPoint));
		if (path == null) {
			path = mainAction.main.mapPathMap.get(pathKay);
		}
		if (path != null) {
			byte[] data = CommandUtil.pathway(agv.getId(), path.getItem());
			String note = "AGV启动，路径ID：" + path.getItem();
			agv.setNextDot(pathKay);
			if (caList == null) {
				mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());// ctrlState,1、行驶
				// 刷新列表
				mainAction.main.agvMap.put(agv.getId(), agv);
			} else {// 判断交管区是否可通行
				int[] caIds = new int[caList.size()];
				for (int i = 0; i < caList.size(); i++) {
					caIds[i] = caList.get(i).getId();
				}
				Guidepost gp = mainAction.main.guidepostMap.get(lastPoint);
				driveAgv(caList, agv, data, note, gp, caIds);
			}
		} else {
			String msg = "找不到对应线路，pathKay:" + pathKay;
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
	}

	/**
	 * 下发多段路径
	 * 
	 * @param agv:当前AGV
	 * @param start:线路开始点
	 * @param end:线路终点
	 */
	public void multiPath(Agv agv, int start, int end) {
		;
		String pathKey = start + "_" + end;
		Path path = mainAction.main.mapPathMap.get(pathKey);
		// logger.info("下发多段线：" + pathKey);
		if (path != null) {
			agv.setGoal(end);// 设置AGV的目的
			if (path.getItem() > 0) {// 单段路径，直接下发线路号
				specifyPath(agv, start, end, null);
//				specifyPath4NumOrDot(agv, start, end, null);
			} else {
				// 多段路径
				agv.setIsMultiPath(1);// 执行多段路径
				agv.setStartPoint(start);
				agv.setEndPoint(end);
				mainAction.main.agvMap.put(agv.getId(), agv);
				// 向AGV下发第一段线路号
				String pStr = path.getNodeArr();
				String[] arr = pStr.split(",");
				int sp = Integer.parseInt(arr[0]);
				int ep = Integer.parseInt(arr[1]);
				specifyPath(agv, sp, ep, null);
//				specifyPath4NumOrDot(agv, sp, ep, null);
			}
		} else {
			String msg = "找不到对应线路，pathKey:" + pathKey;
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
	}

	/**
	 * 下发多段路径（中段路线）
	 * 
	 * @param agv:当前AGV
	 * @param start:线路开始点
	 * @param end:线路终点
	 */
	public void multiPath4z(Agv agv, int start, int end) {
		String pathKey = start + "—" + end;
		String pathKey2 = start + "_" + end;
		Path path = mainAction.main.mapPathMap.get(pathKey);
		if (path == null) {
			path = mainAction.main.mapPathMap.get(pathKey2);
		}
		// logger.info("下发多段线：" + pathKey);
		if (path != null) {
			agv.setGoal(end);// 设置AGV的目的
			if (path.getItem() > 0) {// 单段路径，直接下发线路号
//				specifyPath(agv, start, end, null);
				specifyPath4NumOrDot(agv, start, end, null);
			} else {
				// 多段路径
				agv.setIsMultiPath(1);// 执行多段路径
				agv.setStartPoint(start);
				agv.setEndPoint(end);
				agv.setGoal(end);
				mainAction.main.agvMap.put(agv.getId(), agv);
				// 向AGV下发第一段线路号
				String pStr = path.getNodeArr();
				String[] arr = pStr.split(",");
				int sp = agv.getLastPoint();
				int ep = 0;
				if (arr.length > 0) {
					for (int i = 0; i < arr.length; i++) {
						String lastPoint = "" + agv.getLastPoint();
						if (arr[i].equals(lastPoint)) {
							int arri = i + 1;
							ep = Integer.valueOf(arr[arri]);
							break;
						}
					}
				}
//				specifyPath(agv, sp, ep, null);
				specifyPath4NumOrDot(agv, sp, ep, null);
			}
		} else {
			agv.setGoal(end);
			specifyPath4NumOrDot(agv, start, end, null);
		}
	}

	/**
	 * 让AGV从工位的离开点再次进入对接
	 * 
	 * @param agv
	 * @param num
	 */
	public void goBack(Agv agv, int num) {
		for (Map.Entry<String, Path> mp : mainAction.main.mapPathMap.entrySet()) {
			if (mp.getKey().indexOf("_" + num) > -1) {
				Path path = mp.getValue();
				byte[] data = CommandUtil.pathway(agv.getId(), path.getItem());
				String note = "AGV启动，路径ID：" + path.getItem();
				agv.setGoal(num);
				Park p = mainAction.getParkByOutNum(num);
				Station station = mainAction.getStationByName(p.getStationName());
				station.setJoinAgvId(agv.getId());
				agv.setNextDot(path.getKey());
				if (path.getItem() > 0) {
					mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());// ctrlState,1、行驶
					// 刷新列表
					mainAction.main.agvMap.put(agv.getId(), agv);
					break;
				}
			}
		}
	}

	/**
	 * 根据机台去获取相对应的缓存架
	 * 
	 * @param station
	 * @return
	 */
	public List<CacheShelf> getcacheShelf4Id(Station station) {
		List<CacheShelf> cacheShelfList = new ArrayList<CacheShelf>();
		for (Map.Entry<String, CacheShelf> m : mainAction.main.cacheShelfMap.entrySet()) {
			CacheShelf cache = m.getValue();
			if (cache.getStationId() == station.getId()) {
				cacheShelfList.add(cache);
			}
		}
		return cacheShelfList;
	}

	/**
	 * 获取缓存架机台
	 * 
	 * @param step
	 * @param pGroup
	 * @return
	 */
	public Station getcacheStation(int step, int pGroup) {
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			Station sta = m.getValue();
			if (sta.getStep() == step && sta.getType() == 3) {
				List<CacheShelf> cache = getcacheShelf4Id(sta);
				for (CacheShelf cacheShelf : cache) {
					if (cacheShelf.getPGrounp() == pGroup) {
						station = sta;
					}
				}
			}
		}
		return station;
	}

	/**
	 * 保存缓存架的信息
	 * 
	 * @param station
	 */
	public void saveCacheShelf(Station station, byte[] data) {
		List<CacheShelf> ca = new ArrayList<CacheShelf>();
		if (station.getType() == 3) {
			ca = getcacheShelf4Id(station);
		}
		if (ca.size() > 0) {
			for (CacheShelf cacheShelf : ca) {
				byte[] in = { 0, 0, 0, data[cacheShelf.getInByte()] };
				byte[] out = { 0, 0, 0, data[cacheShelf.getOutByte()] };
				cacheShelf.setInFlag(CommandUtil.toIntH(in));
				cacheShelf.setOutFlag(CommandUtil.toIntH(out));
				mainAction.main.cacheShelfMap.put(cacheShelf.getName(), cacheShelf);
			}
		}
	}
}
